package cn.merlulin.monitor.domain.service.impl;

import cn.merlulin.monitor.domain.model.entity.MonitorDataEntity;
import cn.merlulin.monitor.domain.model.entity.MonitorDataMapEntity;
import cn.merlulin.monitor.domain.model.entity.MonitorFlowDesignEntity;
import cn.merlulin.monitor.domain.model.vo.GatherNodeExpressionVO;
import cn.merlulin.monitor.domain.model.vo.MonitorTreeConfigVO;
import cn.merlulin.monitor.domain.repository.IMonitorRepository;
import cn.merlulin.monitor.domain.service.ILogAnalyticalService;
import cn.merlulin.monitor.types.Constants;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Merlin
 * @version 1.0
 * @email 756151581@qq.com
 * @desc 日志解析服务实现类
 * @date 2025/1/16 18:29
 */
@Slf4j
@Service
public class LogAnalyticalService implements ILogAnalyticalService {

    @Resource
    private IMonitorRepository monitorRepository;

    @Override
    public void doAnalytical(String systemName, String className, String methodName, List<String> logList) throws OgnlException {
        List<GatherNodeExpressionVO> gatherNodeExpressionVOS = monitorRepository.queryGatherNodeExpression(systemName, className, methodName);
        if (null == gatherNodeExpressionVOS || gatherNodeExpressionVOS.isEmpty()) {
            return;
        }
        for (GatherNodeExpressionVO gatherNodeExpressionVO : gatherNodeExpressionVOS) {
            String monitoryName = monitorRepository.queryMonitoryNameByMonitorId(gatherNodeExpressionVO.getMonitorId());
            List<GatherNodeExpressionVO.Field> fields = gatherNodeExpressionVO.getFields();
            for (GatherNodeExpressionVO.Field field : fields) {
                // 1. 获取监控数据规则的日志索引
                Integer logIndex = field.getLogIndex();
                // 2. 获取当前监控日志的监控对象名字
                String logName = logList.get(0);
                // 3. 如果当前监控日志的监控对象名字和监控数据规则的日志名字不一致，则跳过
                if (!logName.equals(field.getLogName())) {
                    continue;
                }
                String logStr = logList.get(logIndex);
                String attributeValue = "";
                if ("Object".equals(field.getLogType())) {
                    // 4. 如果监控数据规则的日志类型是Object，则使用OGNL解析Object类型的日志
                    OgnlContext context = new OgnlContext();
                    context.setRoot(JSONObject.parseObject(logStr));
                    Object root = context.getRoot();
                    attributeValue = String.valueOf(Ognl.getValue(field.getAttributeOgnl(), context, root));
                } else {
                    // 5. 如果监控数据规则的日志类型不是Object，则直接获取日志中的属性值(注意去除左右两别多余空格，或者有冒号的特殊情况）
                    attributeValue = logStr.trim();
                    if (attributeValue.contains(Constants.COLON)) {
                        attributeValue = attributeValue.split(Constants.COLON)[1].trim();
                    }
                }
                MonitorDataEntity monitorDataEntity = MonitorDataEntity.builder()
                        .monitorId(gatherNodeExpressionVO.getMonitorId())
                        .monitorName(monitoryName)
                        .monitorNodeId(gatherNodeExpressionVO.getMonitorNodeId())
                        .systemName(gatherNodeExpressionVO.getGatherSystemName())
                        .clazzName(gatherNodeExpressionVO.getGatherClazzName())
                        .methodName(gatherNodeExpressionVO.getGatherMethodName())
                        .attributeName(field.getAttributeName())
                        .attributeField(field.getAttributeField())
                        .attributeValue(attributeValue)
                        .build();
                monitorRepository.saveMonitorData(monitorDataEntity);
            }
        }


    }

    @Override
    public List<MonitorDataMapEntity> queryMonitorDataMapEntityList() {
        return monitorRepository.queryMonitorDataMapEntityList();
    }

    @Override
    public MonitorTreeConfigVO queryMonitorFlowData(String monitorId) {
        return monitorRepository.queryMonitorFlowData(monitorId);
    }

    @Override
    public List<MonitorDataEntity> queryMonitorDataEntityList(MonitorDataEntity monitorDataEntity) {
        return monitorRepository.queryMonitorDataEntityList(monitorDataEntity);
    }

    @Override
    public void updateMonitorFlowDesign(MonitorFlowDesignEntity monitorFlowDesignEntity) {
        monitorRepository.updateMonitorFlowDesign(monitorFlowDesignEntity);
    }
}
